package com.siao.core;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Properties;

import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;

/**
 * @author SiaoLeon
 * 配置文件管理类（单例模式）
 */
public class Configuration {

	private static final Logger logger = LoggerFactory.getLogger("Configuration");

	/**
	 * 单例对象
	 */
	private static Configuration Instance;

	/**
	 * 获取单例
	 * @return
	 */
	public static Configuration getInstance() {
		if (Instance == null) {
			Instance = new Configuration();
		}
		return Instance;
	}

	/**
	 * 配置文件路径
	 */
	private File path;

	/**
	 * 配置文件路径
	 * @return
	 */
	public File getPath() {
		return this.path;
	}

	/**
	 * 配置对象
	 */
	private Properties properties = new Properties();

	/**
	 * 获取配置
	 * @param key 键名
	 * @return
	 */
	public String getPropertie(String key) {
		return this.properties.getProperty(key);
	}

	/**
	 * 获取配置
	 * @param key 键名
	 * @param serializable 实现ISerializable接口的序列化编码器
	 * @return
	 */
	public Object getPropertie(String key, ISerializable serializable) {
		return serializable.unserialize(this.properties.getProperty(key));
	}

	/**
	 * 获取配置
	 * @param key 键名
	 * @param defaultValue 默认值
	 * @return
	 */
	public String getPropertie(String key, String defaultValue) {
		return this.properties.getProperty(key, defaultValue);
	}

	/**
	 * 获取配置
	 * @param key 键名
	 * @param defaultValue 默认值
	 * @param serializable 实现ISerializable接口的序列化编码器
	 * @return
	 */
	public Object getPropertie(String key, String defaultValue, ISerializable serializable) {
		return serializable.unserialize(this.properties.getProperty(key, defaultValue));
	}

	/**
	 * 设置并加载配置路径中的配置文件
	 * @param directory 文件夹路径
	 */
	public void setFilePath(File directory) {
		if (!directory.exists()) {
			directory = new File("./config");
		}

		if (!directory.exists()) {
			directory = new File("../config");
		}

		if (!directory.exists()) {
			return;
		}

		if (!directory.isDirectory()) {
			logger.error(directory + "不是一个有效的配置文件目录");
			return;
		}

		this.path = directory;
		this.loadLogback();
		this.loadProperties();
	}

	private void loadProperties() {
		FilenameFilter fileFilter = new FilenameFilter() {
			public boolean accept(File dir, String name) {
				return name.toLowerCase().endsWith(".properties");
			}
		};

		File[] files = this.path.listFiles(fileFilter);

		for (int i = 0; i < files.length; ++i) {
			try {
				FileInputStream file = new FileInputStream(files[i]);
				this.properties.load(file);
				file.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private void loadLogback() {
		String filePath = path.getPath();

		if (!filePath.endsWith("/")) {
			filePath = filePath + "/";
		}

		File file = new File(filePath + "logback.xml");
		if (!file.exists()) {
			logger.warn("未加载Logger配置文件：logback.xml");
			return;
		}

		ILoggerFactory loggerFactory = LoggerFactory.getILoggerFactory();
		LoggerContext loggerContext = (LoggerContext) loggerFactory;
		loggerContext.reset();
		JoranConfigurator configurator = new JoranConfigurator();
		configurator.setContext(loggerContext);

		try {
			configurator.doConfigure(file);
		} catch (JoranException e) {
			e.printStackTrace();
		}
	}

}
